<#include "license.ftl">
<@license/>
<#include "macro.ftl">
package ${doc.all.package}.gwt.client;

import com.google.gwt.activity.shared.ActivityManager;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.logical.shared.SelectionEvent;
import com.google.gwt.event.logical.shared.SelectionHandler;
import com.google.gwt.http.client.UrlBuilder;
import com.google.gwt.i18n.client.LocaleInfo;
import com.google.web.bindery.event.shared.EventBus;
import com.google.gwt.json.client.JSONArray;
import com.google.gwt.json.client.JSONParser;
import com.google.gwt.place.shared.Place;
import com.google.gwt.place.shared.PlaceHistoryHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.*;
import redora.client.constants.RedoraConstants;
import redora.client.constants.RedoraMessages;
import redora.client.mvp.AppPlaceHistoryMapper;
import redora.client.mvp.BrowsePlace;
import redora.client.mvp.ClientFactory;
import redora.client.ui.RedoraResource;
import redora.client.util.GWTViewUtil;
import redora.configuration.rdo.gwt.model.RedoraConfiguration;
import redora.configuration.rdo.gwt.mvp.UpgradeEvent;
import redora.configuration.rdo.gwt.mvp.service.RedoraConfigurationService;
import ${doc.all.package}.gwt.mvp.AppActivityMapper;

import java.util.logging.Logger;

import static com.google.gwt.dom.client.Style.Display.BLOCK;
import static com.google.gwt.dom.client.Style.Unit.EM;
import static com.google.gwt.dom.client.Style.Unit.PX;
import static com.google.gwt.user.client.ui.HasHorizontalAlignment.ALIGN_RIGHT;

/**
* @author Redora (www.redora.net)
*/
public class GWTShowcase implements EntryPoint {
    static Logger l = Logger.getLogger("GWTShowcase");

    static RedoraConstants redoraConstants = GWT.create(RedoraConstants.class);
    static RedoraResource redoraResource = GWT.create(RedoraResource.class);
    static RedoraMessages redoraMessages = GWT.create(RedoraMessages.class);

    Place defaultPlace = new BrowsePlace("Product", 0);
    final ScrollPanel appWidget = new ScrollPanel();
    final HorizontalPanel north = new HorizontalPanel();
    final StackLayoutPanel menu = new StackLayoutPanel(EM);
    final FlowPanel models = new FlowPanel();
    final FlowPanel data = new FlowPanel();
    final FlowPanel upgrade = new FlowPanel();

    Anchor dropAllLink;
    Anchor checkLink;
    Anchor upgradeLink;

    ClientFactory clientFactory = GWT.create(ClientFactory.class);
    PlaceHistoryHandler historyHandler;

    @Override
    public void onModuleLoad() {

        RootPanel.getBodyElement().removeChild(RootPanel.get("loadingWrapper").getElement());

        EventBus eventBus = clientFactory.getEventBus();

        ActivityManager activityManager = new ActivityManager(new AppActivityMapper(clientFactory), eventBus);
        activityManager.setDisplay(appWidget);

        AppPlaceHistoryMapper historyMapper = GWT.create(AppPlaceHistoryMapper.class);
        historyHandler = new PlaceHistoryHandler(historyMapper);
        historyHandler.register(clientFactory.getPlaceController(), eventBus, defaultPlace);

        RootLayoutPanel.get().clear();
        DockLayoutPanel main = new DockLayoutPanel(PX);

        north.setWidth("100%");
        north.add(new HTML(redoraConstants.name()));
        north.add(GWTViewUtil.createMessageLabel());
        ListBox localeBox = getLocaleListBox();
        north.add(localeBox);
        north.setCellHorizontalAlignment(localeBox, ALIGN_RIGHT);

        menu.add(data, new HTML(redoraConstants.data()), 2);
        menu.add(models, new HTML(redoraConstants.model()), 2);
        menu.add(upgrade, new HTML(redoraConstants.upgrade()), 2);
        initUpgradeMemu();
        main.addNorth(north, 30);
        main.addSouth(new HTML(redoraConstants.disclaimer()), 20);
        main.addWest(menu, 200);
        main.add(appWidget);

        RootLayoutPanel.get().setStyleName(redoraResource.css().redoraViewPort());
        RootLayoutPanel.get().add(main);

        bind();

        historyHandler.handleCurrentHistory();
        RedoraConfigurationService.getInstance().findModels();
    }

    public void bind() {
        menu.addSelectionHandler(new SelectionHandler<Integer>() {
            @Override
            public void onSelection(SelectionEvent<Integer> integerSelectionEvent) {
                if (integerSelectionEvent.getSelectedItem() == 2)
                    clientFactory.getPlaceController().goTo(
                            new BrowsePlace(RedoraConfiguration.class.getName(), RedoraConfiguration.DefaultFinder.FindAll.ordinal()));
            }
        });
        upgradeLink.addClickHandler(new ClickHandler() {

            @Override
            public void onClick(ClickEvent event) {
                RedoraConfigurationService.getInstance().upgradeTable();
            }
        });

        checkLink.addClickHandler(new ClickHandler() {

            @Override
            public void onClick(ClickEvent event) {
                RedoraConfigurationService.getInstance().checkTable();
            }
        });

        dropAllLink.addClickHandler(new ClickHandler() {

            @Override
            public void onClick(ClickEvent event) {
                RedoraConfigurationService.getInstance().dropAllTable();
            }
        });

        clientFactory.getEventBus().addHandler(UpgradeEvent.TYPE, new UpgradeEvent.Handler() {

            @Override
            public void onSuccess(UpgradeEvent upgradeEvent) {
                if (RedoraConfigurationService.Action.findModels.name().equalsIgnoreCase(upgradeEvent.action)) {
                    JSONArray array = JSONParser.parseLenient(upgradeEvent.callback).isArray();
                    for (int i = 0; i < array.size(); i++) {
                        String modelName = array.get(i).isObject().get("objectName").isString().stringValue();
                        models.add(getModelLink(modelName));
                        data.add(getDataLink(modelName));
                    }
                    GWTViewUtil.displayInfo(redoraMessages.findModels());
                } else if (RedoraConfigurationService.Action.upgrade.name().equalsIgnoreCase(upgradeEvent.action)) {
                    GWTViewUtil.displayInfo(redoraMessages.upgradeTable());
                } else if (RedoraConfigurationService.Action.check.name().equalsIgnoreCase(upgradeEvent.action)) {
                    GWTViewUtil.displayInfo(redoraMessages.checkTable());
                } else if (RedoraConfigurationService.Action.dropAll.name().equalsIgnoreCase(upgradeEvent.action)) {
                    GWTViewUtil.displayInfo(redoraMessages.dropAllTable());
                }
            }
        });
    }

    public void initUpgradeMemu() {
        upgradeLink = new Anchor(redoraConstants.upgradeScripts());
        upgrade.add(upgradeLink);
        upgradeLink.getElement().getStyle().setDisplay(BLOCK);
        checkLink = new Anchor(redoraConstants.check());
        upgrade.add(checkLink);
        checkLink.getElement().getStyle().setDisplay(BLOCK);
        dropAllLink = new Anchor(redoraConstants.dropAllTables());
        upgrade.add(dropAllLink);
        dropAllLink.getElement().getStyle().setDisplay(BLOCK);

    }

    public Anchor getModelLink(String modelName) {
        Anchor modelLink = new Anchor(modelName, new BrowsePlace(modelName.toLowerCase(), 0).toString());
        modelLink.getElement().getStyle().setDisplay(BLOCK);
        return modelLink;
    }

    public Anchor getDataLink(String modelName) {
        Anchor dataLink = new Anchor(modelName, new BrowsePlace(modelName.toLowerCase(), 0).toString());
        dataLink.getElement().getStyle().setDisplay(BLOCK);
        return dataLink;
    }

    public static ListBox getLocaleListBox() {
        // Add the option to change the locale
        final ListBox localeBox = new ListBox();
        String currentLocale = LocaleInfo.getCurrentLocale().getLocaleName();
        if (currentLocale.equals("default")) {
            currentLocale = "en";
        }
        String[] localeNames = LocaleInfo.getAvailableLocaleNames();
        for (String localeName : localeNames) {
            if (!localeName.equals("default")) {
                String nativeName = LocaleInfo.getLocaleNativeDisplayName(localeName);
                localeBox.addItem(nativeName, localeName);
                if (localeName.equals(currentLocale)) {
                    localeBox.setSelectedIndex(localeBox.getItemCount() - 1);
                }
            }
        }
        localeBox.addChangeHandler(new ChangeHandler() {
            public void onChange(ChangeEvent event) {
                String localeName = localeBox.getValue(localeBox.getSelectedIndex());
                UrlBuilder builder = Window.Location.createUrlBuilder().setParameter("locale", localeName);
                Window.Location.replace(builder.buildString());
            }
        });

        return localeBox;
    }

}